package com.yantong.service.impl;

import com.yantong.pojo.CentreRate;
import com.yantong.mapper.CentreRateMapper;
import com.yantong.utils.PageUtils;
import com.yantong.mapper.TicketRecordMapper;
import com.yantong.pojo.vo.*;
import com.yantong.mapper.ReportMapper;
import com.yantong.service.ReportService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReportServiceImpl implements ReportService {
    private static final Logger logger = LoggerFactory.getLogger(ReportServiceImpl.class);

    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private CentreRateMapper centreRateMapper;
    @Autowired
    private TicketRecordMapper ticketRecordMapper;

    @Override
    public PageUtils<ReportProductSaleVo> reportProductSale(HashMap<String, Object> map, int offset, int limit) {
        PageUtils<ReportProductSaleVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countProductSale(map);
        if (total > 0) {
            pageUtils.setTotal(total);
            pageUtils.setRows(reportMapper.reportProductSale(map, new RowBounds(offset, limit)));
        }
        return pageUtils;
    }

    @Override
    public List<ReportProductSaleVo> reportProductSale(HashMap<String, Object> map) {
        List<ReportProductSaleVo> list = new ArrayList<>();
        int total = (int) reportMapper.countProductSale(map);
        if (total > 0) {
            list = reportMapper.reportProductSale(map);
        }
        return list;
    }

    @Override
    public PageUtils<ReportProductSaleListVo> reportProductSaleList(HashMap<String, Object> map, int offset,
                                                                    int limit) {
        PageUtils<ReportProductSaleListVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countProductSaleList(map);
        if (total > 0) {
            pageUtils.setTotal(total);
            pageUtils.setRows(reportMapper.reportProductSaleList(map, new RowBounds(offset, limit)));
        }
        return pageUtils;
    }


    /**
     * 前端商户得到商品销量信息
     *
     * @param map
     * @param offset
     * @param limit
     * @return
     */
    @Override
    public List<ReportProductSaleListVo> getReportProductSaleList(HashMap<String, Object> map, int offset,
                                                                  int limit) {
        return reportMapper.getReportProductSaleList(map, new RowBounds(offset, limit));
    }

    /**
     * 前端用商户商品销量总金额
     *
     * @param map
     * @param rowBounds
     * @return
     */
    @Override
    public ReportProductSaleListVo getReportProductSaleTotal(HashMap<String, Object> map) {
        return reportMapper.getReportProductSaleTotal(map);
    }

    ;

    @Override
    public List<ReportProductSaleListVo> reportProductSaleList(HashMap<String, Object> map) {
        List<ReportProductSaleListVo> list = new ArrayList<>();
        int total = (int) reportMapper.countProductSaleList(map);
        if (total > 0) {
            list = reportMapper.reportProductSaleList(map);
        }
        return list;
    }

    @Override
    public Map<String, Object> countProductSale(HashMap<String, Object> map, int offset, int limit) {
        List<ReportProductSaleListVo> list = reportMapper.reportProductSaleList(map, new RowBounds(offset, limit));
        ReportProductSaleListVo reportVo = null;
        if (CollectionUtils.isNotEmpty(list)) {
            HashMap<String, Object> map2 = map;
            map2.put("list", list);
            reportVo = reportMapper.reportProductSaleList2(map2);
        }
        BigDecimal amount = new BigDecimal("0");
        Long orderNum = 0L;
        //当前平台页毛利
        BigDecimal baseProfit = new BigDecimal("0");
        //当前页成本价
        BigDecimal costprice = new BigDecimal("0");
        //当前页佣金
        BigDecimal commision = new BigDecimal("0");
        //当前页手续费
        BigDecimal poundage = new BigDecimal("0");
        //汇率
        BigDecimal tradeRate = new BigDecimal("0");
        //总汇率
        BigDecimal totalpoundage = new BigDecimal("0");
        //利润
        BigDecimal profit = new BigDecimal("0");
        //总利润
        BigDecimal totalprofit = new BigDecimal("0");
        //商户商品提点金额
        BigDecimal profitRate = new BigDecimal("0");
        //商户商品提点总金额
        BigDecimal totalProfitRate = new BigDecimal("0");
        //站点提点汇率
        BigDecimal rate = new BigDecimal("0");
        //优惠卷金额
        BigDecimal discountprice = reportVo == null ? new BigDecimal("0") : reportVo.getDiscountprice();
        //积分金额
        BigDecimal deductprice = reportVo == null ? new BigDecimal("0") : reportVo.getDeductprice();
        //余额金额
        BigDecimal deductcredit2 = reportVo == null ? new BigDecimal("0") : reportVo.getDeductcredit2();
        for (ReportProductSaleListVo reportProductSaleListVo : list) {
            amount = amount.add(reportProductSaleListVo.getSumPrice());
		/*	discountprice = discountprice.add(reportProductSaleListVo.getDiscountprice());
			deductprice = deductprice.add(reportProductSaleListVo.getDeductprice());
			deductcredit2 = deductcredit2.add(reportProductSaleListVo.getDeductcredit2());*/
            orderNum = orderNum + reportProductSaleListVo.getSumTotal();
            baseProfit = baseProfit.add(reportProductSaleListVo.getSumprofit() == null ? new BigDecimal("0") : reportProductSaleListVo.getSumprofit());
            costprice = costprice.add(reportProductSaleListVo.getSumcostprice());
            commision = commision.add(reportProductSaleListVo.getSumcommision());
            //汇率配置信息
            CentreRate cr = centreRateMapper.getByCentreId(reportProductSaleListVo.getCentreId());
            if (cr != null) {
                tradeRate = cr.getTradeRate();
                //手续费
                poundage = poundage.add(reportProductSaleListVo.getSumPrice().multiply(cr.getTradeRate()).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP));

                //商户商品提点百分比
                if (cr.getProfitRate() != null) {
                    //商户商品
                    if (!StringUtils.isNotEmpty(reportProductSaleListVo.getBaseproductid())) {
                        //商户商品提点金额
                        profitRate = profitRate.add(reportProductSaleListVo.getSumPrice().multiply(cr.getProfitRate()).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP));
                        rate = cr.getProfitRate();
                    }
                }

            }
        }
        //当前页利润
        profit = amount.subtract(costprice).subtract(commision).subtract(poundage).subtract(profitRate);
        Map<String, Object> result = reportMapper.countTotalProductSale(map);
        Map<String, Object> result2 = reportMapper.countTotalProductSale2(map);
        if (result != null) {
            map.put("baseId", 1);
            //得到商户商品总金额
            Map<String, Object> productResult = reportMapper.countTotalProductSale(map);
            //总商户商品提点金额
            if (productResult != null) {
                totalProfitRate = new BigDecimal(productResult.get("totalAmount").toString()).multiply(rate).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP);
            }
            //总手续费
            totalpoundage = new BigDecimal(result.get("totalAmount").toString()).multiply(tradeRate).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP);
            //总利润
            totalprofit = new BigDecimal(result.get("totalAmount").toString()).subtract(new BigDecimal(result.get("totalcostprice").toString()))
                    .subtract(new BigDecimal(result.get("totalcommision").toString())).subtract(totalpoundage).subtract(totalProfitRate);
            result.put("amount", amount);
            result.put("baseProfit", baseProfit);
            result.put("orderNum", orderNum);
            result.put("costprice", costprice);
            result.put("commision", commision);
            result.put("poundage", poundage);
            result.put("totalpoundage", totalpoundage);
            result.put("profit", profit);
            result.put("totalprofit", totalprofit);
            result.put("profitRate", profitRate);
            result.put("totalProfitRate", totalProfitRate);
            result.put("discountprice", discountprice);
            result.put("deductprice", deductprice);
            result.put("deductcredit2", deductcredit2);
            result.put("sumbasecostprice", result.get("sumbasecostprice"));
            result.put("sumDiscountprice", result2.get("discountprice"));
            result.put("sumDeductprice", result2.get("deductprice"));
            result.put("sumDeductcredit2", result2.get("deductcredit2"));
        }
        return result;
    }

    @Override
    public Map<String, Object> countTotalProductbaseSale(HashMap<String, Object> map) {
        return reportMapper.countTotalProductbaseSale(map);
    }

    @Override
    public PageUtils<ReportMemberSaleVo> reportMemberSale(HashMap<String, Object> map, int offset, int limit) {
        PageUtils<ReportMemberSaleVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countMemberSale(map);
        if (total > 0) {
            pageUtils.setTotal(total);
            List<ReportMemberSaleVo> list = reportMapper.reportMemberSale(map);
            if (CollectionUtils.isNotEmpty(list)) {
                int totalOrder = 0, totalProduct = 0;
                BigDecimal totalPrice = new BigDecimal(0);
                for (ReportMemberSaleVo vo : list) {
                    totalOrder += vo.getSumOrder();
                    totalProduct += vo.getSumProduct();
                    totalPrice = totalPrice.add(vo.getSumPrice());
                }
                DecimalFormat df = new DecimalFormat("0.0000");
                for (ReportMemberSaleVo vo : list) {
                    if (vo.getSumOrder() == 0) {
                        vo.setOrderRate("0");
                    } else {
                        vo.setOrderRate(totalOrder == 0 ? 0 + "" : df.format(vo.getSumOrder() / (double) totalOrder * 100));
                    }
                    if (vo.getSumProduct() == 0) {
                        vo.setProductRate("0");
                    } else {
                        vo.setProductRate(totalProduct == 0 ? 0 + "" : df.format(vo.getSumProduct() / (double) totalProduct * 100));
                    }
                    if (totalPrice.compareTo(new BigDecimal("0")) != 0) {
                        vo.setPriceRate(divide(vo.getSumPrice().divide(totalPrice, 6, BigDecimal.ROUND_HALF_EVEN)));
                    } else {
                        vo.setPriceRate("0.00");
                    }

                }
            }
            pageUtils.setRows(list);
        }
        return pageUtils;
    }

    @Override
    public List<ReportMemberSaleVo> reportMemberSale(HashMap<String, Object> map) {
        List<ReportMemberSaleVo> list = new ArrayList<>();
        int total = (int) reportMapper.countMemberSale(map);
        if (total > 0) {
            list = reportMapper.reportMemberSale(map);
            if (CollectionUtils.isNotEmpty(list)) {
                int totalOrder = 0, totalProduct = 0;
                BigDecimal totalPrice = new BigDecimal(0);
                for (ReportMemberSaleVo vo : list) {
                    totalOrder += vo.getSumOrder();
                    totalProduct += vo.getSumProduct();
                    totalPrice = totalPrice.add(vo.getSumPrice());
                }
                DecimalFormat df = new DecimalFormat("0.0000");
                for (ReportMemberSaleVo vo : list) {
                    if (vo.getSumOrder() == 0) {
                        vo.setOrderRate("0");
                    } else {
                        vo.setOrderRate(totalOrder == 0 ? 0 + "" : df.format(vo.getSumOrder() / (double) totalOrder * 100));
                    }
                    if (vo.getSumProduct() == 0) {
                        vo.setProductRate("0");
                    } else {
                        vo.setProductRate(totalProduct == 0 ? 0 + "" : df.format(vo.getSumProduct() / (double) totalProduct * 100));
                    }
                    if (totalPrice.compareTo(BigDecimal.ZERO) == 0) {
                        vo.setPriceRate("0");
                    } else {
                        vo.setPriceRate(divide(vo.getSumPrice().divide(totalPrice, 6, BigDecimal.ROUND_HALF_EVEN)));
                    }
                }
            }
        }
        return list;
    }

    @Override
    public PageUtils<ReportMemberRefundVo> reportMemberRefund(HashMap<String, Object> map, int offset, int limit) {
        PageUtils<ReportMemberRefundVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countMemberRefund(map);
        if (total > 0) {
            pageUtils.setTotal(total);
            List<ReportMemberRefundVo> list = reportMapper.reportMemberRefund(map);
            if (CollectionUtils.isNotEmpty(list)) {
                int totalCount = list.stream().mapToInt(ReportMemberRefundVo::getCount).sum();
                BigDecimal totalPrice = list.stream().map(ReportMemberRefundVo::getSumPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

                for (ReportMemberRefundVo vo : list) {
                    BigDecimal countResult = BigDecimal.valueOf(vo.getCount() / (float) totalCount).setScale(4, BigDecimal.ROUND_HALF_EVEN);
                    BigDecimal priceResult = vo.getSumPrice().divide(totalPrice, 4, BigDecimal.ROUND_HALF_EVEN);
                    vo.setCountRate(divide(countResult));
                    vo.setPriceRate(divide(priceResult));
                    //vo.setCountRate(divide(vo.getCount(), totalCount));
//					vo.setPriceRate(String.valueOf(vo.getSumPrice().divide(totalPrice, 2, BigDecimal.ROUND_HALF_EVEN)));
                }
            }
            pageUtils.setRows(list);
        }
        return pageUtils;
    }

    @Override
    public PageUtils<ReportTmAchieveVo> tmAchieve(Map<String, Object> params, int offset, int limit) {
        PageUtils<ReportTmAchieveVo> pageUtils = new PageUtils<>();
        int total = reportMapper.countTmAchieve(params);
        if (total > 0) {
            pageUtils.setTotal(total);
            pageUtils.setRows(reportMapper.tmAchieve(params, new RowBounds(offset, limit)));
        }
        return pageUtils;
    }

    @Override
    public List<ReportTmAchieveVo> tmAchieve(Map<String, Object> params) {
        return reportMapper.tmAchieve(params);
    }

    @Override
    public PageUtils<ReportSingleSaleVo> reportSingleSale(HashMap<String, Object> map, int offset, int limit) {
        PageUtils<ReportSingleSaleVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countSingleSale(map);
        if (total > 0) {
            pageUtils.setTotal(total);
            List<ReportSingleSaleVo> list = reportMapper.reportSingleSale(map, new RowBounds(offset, limit));
            int saleTotal = 0;
            BigDecimal priceTotal = new BigDecimal(0);
            for (ReportSingleSaleVo vo : list) {
                saleTotal += vo.getSumTotal();
                priceTotal = priceTotal.add(vo.getSumPrice());
            }
            for (ReportSingleSaleVo vo : list) {
                vo.setPriceRate(divide(vo.getSumPrice().divide(priceTotal, 6, BigDecimal.ROUND_HALF_EVEN)));
                vo.setTotalRate(saleTotal == 0 ? 0 + "" : (vo.getSumTotal() / (double) saleTotal * 100) + "");
            }
            pageUtils.setRows(list);
        }
        return pageUtils;
    }

    public String divide(BigDecimal res) {
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(6);
        String result = numberFormat.format(res.doubleValue() * 100);
        return result;
    }

    @Override
    public Long productsaleZj(HashMap<String, Object> params) {
        return reportMapper.countProductSale(params);
    }

    @Override
    public PageUtils<ReportProductSaleListVo> reportProductbaseSale(HashMap<String, Object> map, int offset, int limit) {
        PageUtils<ReportProductSaleListVo> pageUtils = new PageUtils<>();
        int total = (int) reportMapper.countProductbaseSale(map);
        if (total > 0) {
            List<ReportProductSaleListVo> list = reportMapper.reportProductbaseSale(map, new RowBounds(offset, limit));
            for (int i = 0; i < list.size(); i++) {
                //添加规格
                if (list.get(i).getOskuId() != null) {
                    Map<String, Object> queryMap = map;
                    //平台商品
                    if (list.get(i).getBaseproductid() != null) {
                        queryMap.put("baseproductid", list.get(i).getBaseproductid());
                        //设置规格
                        list.get(i).setOptionname(reportMapper.getSkuNameById(queryMap));
                    } else {
                        //商户商品
                        if (list.get(i).getProductId() != null) {
                            queryMap.put("productId", list.get(i).getProductId());
                            //设置规格
                            list.get(i).setOptionname(reportMapper.getSkuNameById(queryMap));
                        }
                    }
                }
            }
            pageUtils.setTotal(total);
            pageUtils.setRows(list);
        }
        return pageUtils;
    }

    @Override
    public List<ReportProductSaleListVo> reportProductbaseSale(HashMap<String, Object> map) {
        return reportMapper.reportProductbaseSale(map);
    }

    @Override
    public List<ReportTmAchieveVo> reportProductSaleDetail(HashMap<String, Object> map) {
        if (map.get("skuId") != null && Long.valueOf(map.get("skuId").toString()) == 0) {
            map.remove("skuId");
        }
        return reportMapper.reportProductSaleDetail(map);
    }

    @Override
    public PageUtils<ReportTmBillVo> tmBill(Map<String, Object> params, int offset, int limit) {
        PageUtils<ReportTmBillVo> pageUtils = new PageUtils<>();
        int total = reportMapper.countTmBill(params);
        if (total > 0) {
            pageUtils.setTotal(total);
            List<ReportTmBillVo> entityList = reportMapper.tmBill(params, new RowBounds(offset, limit));
            for (ReportTmBillVo entity : entityList) {
                //计算门店，商户，平台优惠券抵扣金额
                Map map = new HashMap();
                map.put("centreId", entity.getCentreId());
                map.put("month", entity.getMonth());
                BigDecimal centreCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                entity.setCentreCouponDeductTotal(centreCouponDeductTotal);

                map.clear();
                map.put("centreId", entity.getCentreId());
                map.put("teamId", entity.getTmid());
                map.put("month", entity.getMonth());
                BigDecimal teamCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                entity.setTeamCouponDeductTotal(teamCouponDeductTotal);

                map.clear();
                map.put("platform", "1");//有值就查询平台
                map.put("month", entity.getMonth());
                BigDecimal platformCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                entity.setPlatformCouponDeductTotal(platformCouponDeductTotal);

                /**
                 * 计算结算总金额
                 * 结算总金额 = 实际支付金额+商户优惠券抵扣金额+平台优惠券抵扣金额-积分抵扣总额-满减抵扣-其他佣金
                 */
                BigDecimal settlementPrice = entity.getTotalPayPrice().add(centreCouponDeductTotal).add(platformCouponDeductTotal);
                settlementPrice = settlementPrice.subtract(entity.getTotalDeductPrice()).subtract(entity.getTotalCommision1())
                        .subtract(entity.getTotalCommision2()).subtract(entity.getTotalCommision3()).subtract(entity.getTotalCommision4())
                        .subtract(entity.getTotalCommision5()).subtract(entity.getTotalCommision6())
                        .subtract(entity.getTotalCommision7()).subtract(entity.getTotalCommision8())
                        .subtract(entity.getTotalFullDiscountPrice());
                entity.setSettlementPrice(settlementPrice);
            }

            pageUtils.setRows(entityList);
        }
        return pageUtils;
    }


    @Override
    public List<ReportTmBillVo> getAllBillList(Map<String, Object> params) {
            List<ReportTmBillVo> entityList = reportMapper.tmBill(params, new RowBounds());
            if(entityList != null && entityList.size() > 0) {
                for (ReportTmBillVo entity : entityList) {
                    //计算门店，商户，平台优惠券抵扣金额
                    Map map = new HashMap();
                    map.put("centreId", entity.getCentreId());
                    map.put("month", entity.getMonth());
                    BigDecimal centreCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                    entity.setCentreCouponDeductTotal(centreCouponDeductTotal);

                    map.clear();
                    map.put("centreId", entity.getCentreId());
                    map.put("teamId", entity.getTmid());
                    map.put("month", entity.getMonth());
                    BigDecimal teamCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                    entity.setTeamCouponDeductTotal(teamCouponDeductTotal);

                    map.clear();
                    map.put("platform", "1");//有值就查询平台
                    map.put("month", entity.getMonth());
                    BigDecimal platformCouponDeductTotal = ticketRecordMapper.getSumTicketAmount(map);
                    entity.setPlatformCouponDeductTotal(platformCouponDeductTotal);

                    /**
                     * 计算结算总金额
                     * 结算总金额 = 实际支付金额+商户优惠券抵扣金额+平台优惠券抵扣金额-门店优惠券抵扣金额-积分抵扣总额-满减抵扣-其他佣金
                     */
                    BigDecimal settlementPrice = entity.getTotalPayPrice().add(centreCouponDeductTotal).add(platformCouponDeductTotal);
                    settlementPrice = settlementPrice.subtract(teamCouponDeductTotal).subtract(entity.getTotalDeductPrice()).subtract(entity.getTotalCommision1())
                            .subtract(entity.getTotalCommision2()).subtract(entity.getTotalCommision3()).subtract(entity.getTotalCommision4())
                            .subtract(entity.getTotalCommision5()).subtract(entity.getTotalCommision6())
                            .subtract(entity.getTotalCommision7()).subtract(entity.getTotalCommision8())
                            .subtract(entity.getTotalFullDiscountPrice());
                    entity.setSettlementPrice(settlementPrice);
                }
            }


        return entityList;
    }

}
